#include "Node.hh"

#include <iostream>

using namespace sirtet;
using namespace std;

Node::Node(const char *name) : name(name)
{
}

Node::~Node()
{
    cout << name << " Dropped." << endl;
}

void Node::update()
{
    cout << name << " Update.";
    if (parent != nullptr)
    {
        cout << " Parent is " << parent->name << '.';
    }
    cout << endl;
    for (auto &child : children)
    {
        child->update();
    }
}

void Node::after_update()
{
}

void Node::add_child(std::unique_ptr<Node> &&child)
{
    child->parent = this;
    children.push_back(std::move(child));
}

size_t Node::child_count()
{
    return children.size();
}

std::unique_ptr<Node> *Node::find_child(const char *name)
{
    for (auto &child : children)
    {
        if (child->name == name)
        {
            return &child;
        }
    }
    return nullptr;
}

std::unique_ptr<Node> Node::remove_child(const char *name)
{
    return remove_child([&](auto &x) { return x->name == name; });
}

std::unique_ptr<Node> Node::remove_child(std::function<bool(std::unique_ptr<Node> &)> predicate)
{
    auto it = std::find_if(children.begin(), children.end(), predicate);
    if (it != children.end())
    {
        return std::move(*children.erase(it));
    }
    return nullptr;
}

bool Node::has_parent()
{
    return parent != nullptr;
}

Node &Node::get_parent()
{
    return *parent;
}
